#pragma once

#include "Collider.h"

#include <vector>
#include <map>
#include "QuadTree.h"

enum ECollisionMethod{
	COLL_BRUTE_FORCE = 0,
	COLL_QUAD_TREE
};

class Entity;
class CollisionManager : public ColliderListener
{
public:
	typedef void (CollisionManager::*HitFuncPtr)(Entity*, Entity*);
	typedef std::map<std::pair<int, int>, HitFuncPtr> HitMap;
	CollisionManager(void);
	~CollisionManager(void);

	void Init();
	void Update();
	void AddCollider(Collider* p_collider);
	void RemoveMe(Collider* collider);
	void Shut();
	void SetCollisionMethod(int method) { m_collision_method = method; }
	void CheckCollision(Entity* lhs, Entity* rhs);

private:
	inline void ClearColliders();
	std::pair<int, int> MakeIntPair(int, int);
	void N64BasicTower(Entity* n64, Entity* basic_tower);
	void BasicTowerN64(Entity* basic_tower, Entity* n64) { N64BasicTower(n64, basic_tower); }
	void ProjectileEnemy(Entity* projectile, Entity* enemy);
	void EnemyProjectile(Entity* enemy, Entity* projectile) {}
	void EnemyScan(Entity* enemy, Entity* basic_tower);
	void ScanEnemy(Entity* basic_tower, Entity* enemy) { EnemyScan(enemy, basic_tower); }
	void WallEnemyprojectile(Entity* wall, Entity* enemy_projectile);
	void EnemyprojectileWall(Entity* enemy_projectile, Entity* wall) {}
	void EnemySlowprojectile(Entity* enemy, Entity* slow_projectile);
	void SlowprojectileEnemy(Entity* slow_projectile, Entity* enemy) {}
	
	int m_collision_method;
	HitMap m_collision_callbacks;
	std::vector<Collider*> m_colliders;
	QuadTree m_quad_tree;
	AABB m_collision_boundary;
};